package org.steven.crm.core.service.salebill;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.steven.sequence.generater.SnowflakeGenerator;
import com.steven.xdb.dbmanager.DBManager;
import com.steven.xdb.pagination.query.AbstractQueryDataList;
import org.apache.commons.lang3.StringUtils;
import org.steven.crm.core.Constants;
import org.steven.crm.core.data.CascadeQueryConfig;
import org.steven.crm.core.data.TableRelation;
import org.steven.crm.core.dto.salebill.SaveSaleBillProductRequest;
import org.steven.crm.core.dto.salebill.SaveSaleBillRequest;
import org.steven.crm.core.query.SaleBillQueryDataList;
import org.steven.crm.core.service.BaseService;
import org.steven.crm.core.service.system.SystemFileService;
import org.steven.crm.core.utils.JSONUtil;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author wuzw
 * @Date 2024/6/21 15:42
 * @Version 1.0
 */
public class SaleBillService extends BaseService {
    private static SaleBillImageService imageService = new SaleBillImageService();

    private static SaleBillProductService saleBillProductService = new SaleBillProductService();

    private static SystemFileService systemFileService = new SystemFileService();
    @Override
    protected String getTable() {
        return "saleBill";
    }

    @Override
    protected AbstractQueryDataList getQueryDataList() {
        return new SaleBillQueryDataList();
    }

    @Override
    protected String getDataSourceName() {
        return null;
    }

    @Override
    protected List<CascadeQueryConfig> getCascadeQueryConfigs() {
        List<CascadeQueryConfig> cascadeQueryConfigs = new ArrayList<>();

        cascadeQueryConfigs.add(CascadeQueryConfig.builder().build().setSrcColumn("id")
                .setValue("images").setTableRelation(TableRelation.MANY2MANY)
                .setMiddleService(imageService).setMiddleTableSrcColumn("saleBillId")
                .setMiddleTableTargetColumn("imageFileId")
                .setTargetService(systemFileService).setTargetColumn("id")
                .setTargetTableFields(new String[] {"path", "width", "height"}));

        cascadeQueryConfigs.add(CascadeQueryConfig.builder().build().setSrcColumn("id")
                .setValue("products").setTableRelation(TableRelation.ONE2MANY)
                .setTargetService(saleBillProductService).setTargetColumn("saleBillId")
                .setTargetTableFields(new String[] {"id", "productId", "name", "price", "num"}));

        return cascadeQueryConfigs;
    }

    public Map<String, Object> readExtView(String id) throws Exception {
        Map<String, String> k = new HashMap<>();
        k.put("id", id);
        k.put("deleted", "0");
        Map<String, String> data = DBManager.queryOne(getSession(), getTable() +"_V", k);
        Map<String, Object> newData = new HashMap<>();
        newData.putAll(data);

        cascadeQuery(newData);

        return newData;
    }

    public Map<String, String> save(SaveSaleBillRequest request) throws Exception {
        Map<String, String> data = JSONUtil.toMap(request);
        data.putAll(calAmountInfo(request));
        if (StringUtils.isEmpty(request.getId())) {
            data = this.create(data);
        } else {
            data = this.update(request.getId(), data);
        }

        imageService.batchSave(data.get("id"), request.getImages());
        saleBillProductService.batchSave(data.get("id"), request.getProducts());

        return data;
    }

    public Map<String, String> calAmountInfo(SaveSaleBillRequest request) throws Exception {
        BigDecimal productAmount = new BigDecimal("0");
        for (SaveSaleBillProductRequest product : request.getProducts()) {
            productAmount = productAmount.add(new BigDecimal(product.getPrice())
                    .multiply(new BigDecimal(product.getNum())));
        }

        BigDecimal totalAmount = productAmount.add(new BigDecimal(request.getFreightAmount()))
                .subtract(new BigDecimal(request.getDiscountAmount()));

        Map<String, String> data = new HashMap<>();
        data.put("productAmount", productAmount.toString());
        data.put("totalAmount", totalAmount.toString());

        if (request.getPayStatus().equals(Constants.PayStatus.UN_PAY)) {
            data.put("payAmount", "0");
        } else if (request.getPayStatus().equals(Constants.PayStatus.PAY_ALL)) {
            data.put("payAmount", totalAmount.toString());
        }

        return data;
    }
}
